package com.r2coding.server.modules.file.controller;

import com.r2coding.core.response.Result;
import com.r2coding.core.utils.IdUtil;
import com.r2coding.server.common.utils.UserIdUtil;
import com.r2coding.server.modules.file.constants.FileConstants;
import com.r2coding.server.modules.file.context.CreateFolderContext;
import com.r2coding.server.modules.file.context.FileDownloadContext;
import com.r2coding.server.modules.file.context.FilePreviewContext;
import com.r2coding.server.modules.file.context.QueryFolderTreeContext;
import com.r2coding.server.modules.file.po.*;
import com.r2coding.server.modules.file.service.IUserFileService;
import com.r2coding.server.modules.file.vo.FileChunkUploadVo;
import com.r2coding.server.modules.file.vo.FolderTreeNodeVo;
import com.r2coding.server.modules.file.vo.UploadedChunkVo;
import com.r2coding.server.modules.file.vo.UserFileVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import java.util.List;

/**
 * @author 98k灬
 * @version v1.0.0
 * @Description : 文件
 * @Create on : 2023/10/11 12:25
 **/
@Validated
@RestController
public class FileController {
    @Autowired
    private IUserFileService userFileService;

    @GetMapping("/files")
    public Result<?> list(@NotBlank(message = "父文件夹ID不能为空") @RequestParam("parentId") String parentId,
                          @RequestParam(value = "fileTypes", required = false, defaultValue = FileConstants.ALL_FILE_TYPE) String fileTypes) {
        List<UserFileVo> userFileVoList = userFileService.getFileList(parentId, fileTypes);
        return Result.ok(userFileVoList);
    }

    @PostMapping("/file/folder")
    public Result<?> createFolder(@Validated @RequestBody CreateFolderPo createFolderPo) {
        CreateFolderContext folderContext = CreateFolderContext.builder()
                .folderName(createFolderPo.getFolderName())
                .userId(UserIdUtil.get())
                .parentId(IdUtil.decrypt(createFolderPo.getParentId()))
                .build();
        Long folderId = userFileService.createFolder(folderContext);
        return Result.ok(folderId);
    }

    @PutMapping("/file")
    public Result<?> updateFilename(@Validated @RequestBody UpdateFilenamePo updateFilenamePo) {
        userFileService.updateFilename(updateFilenamePo);
        return Result.ok();
    }

    @DeleteMapping("/file")
    public Result<?> delete(@Validated @RequestBody DeleteFilePo deleteFilePo) {
        userFileService.deleteFile(deleteFilePo);
        return Result.ok();
    }

    @PostMapping("/file/sec-upload")
    public Result<?> secUpload(@Validated @RequestBody SecUploadPo secUploadPo) {
        boolean ok = userFileService.secUpload(secUploadPo);
        return ok ? Result.ok() : Result.error();
    }

    @PostMapping("/file/upload")
    public Result<?> upload(@Validated FileUploadPo fileUploadPo) {
        userFileService.upload(fileUploadPo);
        return Result.ok();
    }

    @PostMapping("/file/chunk-upload")
    public Result<?> chunkUpload(@Validated FileChunkUploadPo fileChunkUploadPo) {
        FileChunkUploadVo vo = userFileService.chunkUpload(fileChunkUploadPo);
        return Result.ok(vo);
    }

    @GetMapping("/file/chunk-upload")
    public Result<?> getUploadedChunks(@Validated QueryUploadedChunksPo queryUploadedChunksPo) {
        UploadedChunkVo vo = userFileService.getUploadedChunks(queryUploadedChunksPo);
        return Result.ok(vo);
    }

    @PostMapping("/file/merge")
    public Result<?> mergeFile(@Validated @RequestBody FileChunkMergePo fileChunkMergePo) {
        userFileService.mergeFile(fileChunkMergePo);
        return Result.ok();
    }

    @PostMapping("/file/download")
    public Result<?> download(@Validated @RequestParam(value = "fileId", required = false) String fileId, HttpServletResponse response) {
        FileDownloadContext context = FileDownloadContext.builder()
                .fileId(IdUtil.decrypt(fileId))
                .response(response)
                .userId(UserIdUtil.get()).build();
        userFileService.download(context);
        return Result.ok();
    }

    @GetMapping("/file/preview")
    public Result<?> preview(@Validated @RequestParam(value = "fileId", required = false) String fileId, HttpServletResponse response) {
        FilePreviewContext context = FilePreviewContext.builder()
                .userId(UserIdUtil.get())
                .fileId(IdUtil.decrypt(fileId))
                .response(response)
                .build();
        userFileService.preview(context);
        return Result.ok();
    }

    @GetMapping("/file/folder/tree")
    public Result<?> folderTree() {
        QueryFolderTreeContext context = QueryFolderTreeContext.builder().userId(UserIdUtil.get()).build();
        List<FolderTreeNodeVo> list = userFileService.getFolderTree(context);
        return Result.ok(list);
    }

    @PostMapping("/file/transfer")
    public Result<?> transfer(@Validated @RequestBody TransferFilePo transFerFilePo) {
        userFileService.transfer(transFerFilePo);
        return Result.ok();
    }

    @PostMapping("/file/copy")
    public Result<?> copy(@Validated @RequestBody CopyFilePo copyFilePo) {
        userFileService.copy(copyFilePo);
        return Result.ok();
    }
}
